package server;

import java.util.*;
import java.io.*;
import msgs.*;
/**
 * This is an internal representation of a group chat
 * Team 9: Andrew Hayworth, Brian Parrella, Ryan Kortmann, Nina Papa
 * @author Andrew Hayworth
 */
public class Chat extends Thread implements TTConstants {
	private ArrayList<ConnectedUser> members;
	private ArrayList<String> admins;
	private ArrayList<String[]> msgs;
	private String title;
	private boolean closed;	// true = private group chat, false = public group chat -- also not implemented :)
	private boolean running;
	private boolean adminLogging;
	private File logFile;
	private String logFileName;
	private PrintWriter p;
	
	public Chat(ArrayList<ConnectedUser> members, ArrayList<String> admins, String title, boolean closed) {
		this.members = members;
		this.admins = admins;
		this.title = title;
		this.closed = closed;
		this.running = true;
		this.adminLogging = false;
		this.msgs = new ArrayList<String[]>();
		// set up the chatlog directory...
		File dir = new File ("data/chatlogs");
		if (!(dir.exists())) dir.mkdirs();
		this.logFileName = ("" + (dir.list().length +1) );
		logFile = new File("data/chatlogs/"+logFileName);
		try {
			p = new PrintWriter((new FileWriter(logFile)), true);
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public void run() {
		while (running) {
			if (!(msgs.isEmpty())) { // only work if we have a message
				String theMsg = msgs.get(0)[1];
			//	System.out.println(theMsg);
				String whoSaidIt = msgs.remove(0)[0];
					for (ConnectedUser user : members ) {
					//	System.out.println(user.getName());
						//update each user in the list
						ChatMsg cm = new ChatMsg(theMsg, title);
						cm.setAction(Actions.CHAT_UPDATE);
						cm.setResponse(Responses.OK);
						cm.setName(user.getName());
						cm.setIp(user.getIp());
						cm.setUser(whoSaidIt);
						ClientSender.outQ.add(cm);
						//System.out.println("Sent message to user " + user.getName());
					}
				if (adminLogging) logIt(theMsg);
			}
			else {
				try {
					Thread.sleep(100);	// i'm not sure what was happening here. but chat stopped working until this was in here...
				}
				catch (Exception e) {}
			}
		}
	}
	
	/**
	 * Adds a mesage onto the queue
	 * @param who Person who spoke
	 * @param msg Message they said
	 */
	public void addMsg(String who, String msg) {
		String[] s = {who, msg};
		msgs.add(s);
		//System.out.println("Message queue is empty: " + msgs.isEmpty());
	}
	
	/**
	 * Add a user onto the member list
	 * @param name User to add
	 */
	public void addUser(String name) {
		members.add(TTServer.connTable.get(name));
	}
	
	/**
	 * Remove a user from the list of users
	 * @param name User to remove
	 */
	public void removeUser(String name) {
		// oh, why oh why did i not make this a hashtable?
		// step thru the members list, remove them if their name matches
		Iterator<ConnectedUser> it = members.iterator();
		while (it.hasNext() ) {
			ConnectedUser c = it.next();
			if (c.getName().equals(name)) {
				it.remove();
			}
		}
		System.out.println("Removed user " + name);
		System.out.println("Chat Size " + members.size());
		if (members.size() == 0) {
			killChat();
		}
	}

	/**
	 * @return the members
	 */
	public ArrayList<ConnectedUser> getMembers() {
		return members;
	}

	/**
	 * @param members the members to set
	 */
	public void setMembers(ArrayList<ConnectedUser> members) {
		this.members = members;
	}

	/**
	 * @return the msgs
	 */
	public ArrayList<String[]> getMsgs() {
		return msgs;
	}

	/**
	 * @param msgs the msgs to set
	 */
	public void setMsgs(ArrayList<String[]> msgs) {
		this.msgs = msgs;
	}

	/**
	 * @return the admins
	 */
	public ArrayList<String> getAdmins() {
		return admins;
	}

	/**
	 * @param admins the admins to set
	 */
	public void setAdmins(ArrayList<String> admins) {
		this.admins = admins;
	}

	/**
	 * @return the topic
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @param topic the topic to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	/**
	 * @return the closed
	 */
	public boolean isClosed() {
		return closed;
	}

	/**
	 * @param closed the closed to set
	 */
	public void setClosed(boolean closed) {
		this.closed = closed;
	}
	
	/**
	 * Forcibly kills the chat
	 */
	public void killChat() { 
		this.running = false;
		TTServer.chats.remove(title);
		try {
			p.close();
		}
		catch(Exception e) { e.printStackTrace(); }
	}
	
	/**
	 * Lists the members in the chat
	 * @return Arraylist of members in the chat
	 */
	public ArrayList<String> getMemberNames() {
		ArrayList<String> al = new ArrayList<String>();
		synchronized(members) {
			for (ConnectedUser c : members) {
				al.add(c.getName());
			}
		}
		return al;
	}
	
	/**
	 * Turns on the logging function
	 * @param state True = loggin, false = not logging.
	 */
	public void adminLog(boolean state) {
		this.adminLogging = state;
	}
	
	/**
	 * Print out to the file what was said
	 * @param msg What to print
	 */
	private void logIt(String msg) {
		try {
			p.println(msg);
		}
		catch (Exception e) { e.printStackTrace(); }
	}
}
